// eslint-disable-next-line @typescript-eslint/no-unused-vars
const eventNames = [

] as const // 事件名称

type EventName = (typeof eventNames)[number]

type EventCallback = (...args: any[]) => void

interface IEmitter {
  events: Record<EventName, Set<EventCallback>>
  on: (event: EventName, callback: EventCallback) => void
  emit: (event: EventName, ...args: any[]) => void
  once: (event: EventName, callback: EventCallback) => void
  off: (event: EventName, callback: EventCallback) => void
}

class Emitter implements IEmitter {
  events: Record<EventName, Set<EventCallback>>

  constructor() {
    this.events = {} as Record<EventName, Set<EventCallback>>
  }

  on(event: EventName, callback: EventCallback) {
    if (!this.events[event]) {
      this.events[event] = new Set()
    }
    this.events[event].add(callback)
  }

  emit(event: EventName, ...args: any[]) {
    const callbacks = this.events[event]
    if (callbacks) {
      callbacks.forEach(fn => {
        fn(...args)
      })
    }
  }

  off(event: EventName, callback: EventCallback) {
    const callbacks = this.events[event]
    if (callbacks) {
      callbacks.delete(callback)
    }
  }

  once(event: EventName, callback: EventCallback) {
    const cb: EventCallback = (...args: any[]) => {
      callback(...args)
      this.off(event, cb)
    }
    this.on(event, cb)
  }
}

export const emitter = new Emitter()
